package com.jichangxiu.generator.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import com.jichangxiu.common.annotation.Dynamic;
import com.jichangxiu.common.constant.Constants;
import com.jichangxiu.common.entity.bo.CompareResult;
import com.jichangxiu.common.entity.bo.Record;
import com.jichangxiu.common.entity.bo.ValidateBos;
import com.jichangxiu.common.exception.ServiceException;
import com.jichangxiu.common.utils.ConvertUtils;
import com.jichangxiu.framework.service.impl.BaseServiceImpl;
import com.jichangxiu.framework.utils.CompareUtils;
import com.jichangxiu.framework.utils.DynamicUtils;
import com.jichangxiu.framework.utils.SecurityUtils;
import com.jichangxiu.framework.utils.ValidateUtils;
import com.jichangxiu.generator.config.VelocityInitializer;
import com.jichangxiu.generator.entity.bo.GenColumnBo;
import com.jichangxiu.generator.entity.bo.GenRowBo;
import com.jichangxiu.generator.entity.dto.GenRowDto;
import com.jichangxiu.generator.entity.dto.add.AddGenColumn;
import com.jichangxiu.generator.entity.dto.add.AddGenRow;
import com.jichangxiu.generator.entity.dto.edit.EditGenRow;
import com.jichangxiu.generator.entity.dto.query.QueryGenRow;
import com.jichangxiu.generator.entity.dto.query.QueryTable;
import com.jichangxiu.generator.entity.po.GenCategory;
import com.jichangxiu.generator.entity.po.GenColumn;
import com.jichangxiu.generator.entity.po.GenRow;
import com.jichangxiu.generator.entity.po.GenTemplate;
import com.jichangxiu.generator.entity.vo.*;
import com.jichangxiu.generator.enums.TemplateType;
import com.jichangxiu.generator.mapper.GenColumnMapper;
import com.jichangxiu.generator.mapper.GenRowMapper;
import com.jichangxiu.generator.service.GenCategoryService;
import com.jichangxiu.generator.service.GenColumnService;
import com.jichangxiu.generator.service.GenRowService;
import com.jichangxiu.generator.service.GenTemplateService;
import com.jichangxiu.generator.utils.VelocityUtils;
import org.apache.commons.io.IOUtils;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.Velocity;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.validation.constraints.NotBlank;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.StringReader;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

/**
 * GenRowServiceImpl:
 *
 * @author JiChangXiu
 * @create 2024-06-30 13:31:04
 */
@Service
public class GenRowServiceImpl extends BaseServiceImpl<GenRowMapper, GenRow, GenRowVo> implements GenRowService {

    @Resource
    private GenRowMapper genRowMapper;

    @Resource
    private GenColumnMapper genColumnMapper;

    @Resource
    private GenColumnService genColumnService;

    @Resource
    private GenCategoryService genCategoryService;

    @Resource
    private GenTemplateService genTemplateService;

    /**
     * 导入生成行
     *
     * @param genRowDto 导入行视图对象
     * @return 是否成功
     */
    @Dynamic
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean add(GenRowDto genRowDto) {
        String sourceCode = genRowDto.getSourceCode();
        // 如果前端没有传过来数据源标识，那么这里就用当前租户的数据源
        if (StrUtil.isEmpty(sourceCode))
            sourceCode = SecurityUtils.getTenantSource();
        DynamicUtils.changeSource(sourceCode);
        List<String> nameList = ListUtil.toList(genRowDto.getNameList());
        List<TableVo> tableVoList = genRowMapper.tableVoListByNames(nameList);
        List<ColumnVo> columnVoList = genColumnMapper.columnVoListByNames(nameList);
        if (ObjectUtil.isNotEmpty(tableVoList) && ObjectUtil.isNotEmpty(columnVoList)) {
            Map<String, List<ColumnVo>> columnNameByColumnVoListToMap = columnVoList.stream().collect(Collectors.groupingBy(ColumnVo::getTableName));
            tableVoList.forEach(tableVo -> tableVo.setColumnVoList(columnNameByColumnVoListToMap.get(tableVo.getName())));
        }
        List<AddGenRow> addGenRowList = new ArrayList<>();
        List<AddGenColumn> addGenColumnList = new ArrayList<>();
        tableVoList.forEach(tableVo -> {
            AddGenRow addGenRow = VelocityUtils.initAddGenRow(tableVo);
            if (ObjectUtil.isNotEmpty(addGenRow)) {
                addGenRowList.add(addGenRow);
                addGenColumnList.addAll(addGenRow.getAddGenColumnList());
            }
        });
        if (ObjectUtil.isEmpty(addGenRowList) || ObjectUtil.isEmpty(addGenColumnList))
            throw new ServiceException("没有需要导入的表");
        // 重新换回当前租户数据库
        DynamicUtils.setCurrentTenantSource();
        List<GenRow> genRowList = addGenRowList.stream()
                .map(addGenRow -> addAndEditValidBo(ConvertUtils.convert(addGenRow, GenRowBo.class)))
                .collect(Collectors.toList());
        boolean b1 = true;
        if (ObjectUtil.isNotEmpty(addGenRowList))
            b1 = saveBatch(genRowList);
        boolean b2 = true;
        if (ObjectUtil.isNotEmpty(addGenColumnList))
            b2 = genColumnService.saveBatch(ConvertUtils.convert(addGenColumnList, GenColumn.class));
        DynamicUtils.resetSource();
        return b1 && b2;
    }

    /**
     * 单（多）选删除生成行
     *
     * @param idList 生成行主键列表
     * @return 是否成功
     */
    @Dynamic
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean del(List<String> idList) {
        boolean b1 = getBaseMapper().deleteBatchIds(delValid(idList)) > 0;
        boolean b2 = genColumnService.remove(new LambdaQueryWrapper<GenColumn>().in(GenColumn::getRowId, idList));
        return b1 && b2;
    }

    /**
     * 修改生成行
     *
     * @param editGenRow 修改生成行视图对象
     * @return 是否成功
     */
    @Dynamic
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean edit(EditGenRow editGenRow) {
        boolean b1 = getBaseMapper().updateById(addAndEditValidBo(ConvertUtils.convert(editGenRow, GenRowBo.class))) > 0;
        List<GenColumnBo> uiGenColumnBoList = ConvertUtils.convert(editGenRow.getEditGenColumnList(), GenColumnBo.class);
        List<GenColumnBo> dbGenColumnBoList = ConvertUtils.convert(genColumnService.list(new LambdaQueryWrapper<GenColumn>().in(GenColumn::getRowId, editGenRow.getId())), GenColumnBo.class);
        CompareResult<GenColumnBo> compareResult = CompareUtils.compareList(uiGenColumnBoList, dbGenColumnBoList, GenColumnBo::getId);
        boolean b2 = true;
        List<GenColumnBo> addList = compareResult.getAddList();
        if (ObjectUtil.isNotEmpty(addList)) {
            addList.forEach(genColumnBo -> genColumnBo.setRowId(editGenRow.getId()));
            b2 = genColumnService.saveBatch(ConvertUtils.convert(addList, GenColumn.class));
        }
        List<GenColumnBo> editList = compareResult.getEditList();
        boolean b3 = true;
        if (ObjectUtil.isNotEmpty(editList)) {
            b3 = genColumnService.updateBatchById(ConvertUtils.convert(editList, GenColumn.class));
        }
        List<GenColumnBo> deleteList = compareResult.getDeleteList();
        boolean b4 = true;
        if (ObjectUtil.isNotEmpty(deleteList)) {
            b4 = genColumnService.removeBatchByIds(deleteList.stream().map(GenColumnBo::getId).collect(Collectors.toList()));
        }
        return b1 && b2 && b3 && b4;
    }

    /**
     * 根据主键查询生成行
     *
     * @param id       生成行主键
     * @param isExtend 是否扩展
     * @return 生成行详情
     */
    @Dynamic
    @Override
    public GenRowVo info(@NotBlank(message = "主键不能为空") String id, Boolean isExtend) {
        GenRowVo genRowVo = getBaseMapper().selectJoinOne(GenRowVo.class, buildQueryWrapper(QueryGenRow.builder().id(id).build()));
        if (Boolean.TRUE.equals(isExtend) && ObjectUtil.isNotEmpty(genRowVo)) {
            genRowVo = renderGenRowVoList(ListUtil.toList(genRowVo)).get(0);
            genRowVo = renderChildGenRowVoList(ListUtil.toList(genRowVo)).get(0);
        }
        return genRowVo;
    }

    /**
     * （可分页）查询生成行列表
     *
     * @param queryGenRow 查询视图对象
     * @return （分页）生成行列表
     */
    @Dynamic
    @Override
    public Page<GenRowVo> lists(QueryGenRow queryGenRow) {
        Page<GenRowVo> genRowVoPage = getBaseMapper().selectJoinPage(startPage(), GenRowVo.class, buildQueryWrapper(queryGenRow));
        if (Boolean.TRUE.equals(queryGenRow.getIsExtend())) {
            genRowVoPage.setRecords(renderGenRowVoList(genRowVoPage.getRecords()));
            genRowVoPage.setRecords(renderChildGenRowVoList(genRowVoPage.getRecords()));
        }
        return genRowVoPage;
    }

    /**
     * （可分页）查询生表信息列表
     *
     * @param queryTable 表格查询条件
     * @return （分页）表信息列表
     */
    @Override
    public Page<TableVo> tableVoList(QueryTable queryTable) {
        Page<TableVo> page = startPage();
        List<TableVo> tableList = genRowMapper.tableVoList(queryTable, page);
        page.setRecords(tableList);
        return page;
    }

    /**
     * 代码预览
     *
     * @param rowIdList 主键
     * @return 代码预览
     */
    @Override
    public Record preview(List<String> rowIdList) {
        List<GenRowVo> genRowVoList = voList(new LambdaQueryWrapper<GenRow>().in(GenRow::getId, rowIdList));
        if (ObjectUtil.isEmpty(genRowVoList)) throw new ServiceException("未找到数据");
        renderGenRowVoList(genRowVoList);
        renderChildGenRowVoList(genRowVoList);
        Record record = Record.getRecord();
        genRowVoList.forEach(genRowVo -> {
            if (ObjectUtil.isEmpty(genRowVo.getCategoryId())) throw new ServiceException("未指定使用的模板分类");
            List<GenTemplateVo> genTemplateVoList = genRowVo.getGenTemplateVoList();
            if (ObjectUtil.isEmpty(genTemplateVoList)) throw new ServiceException("未找到模板列表");
            Record result = Record.getRecord();
            // 单表
            if (StrUtil.isEmpty(genRowVo.getChildRowId())) {
                // 单表
                VelocityInitializer.initVelocity();
                VelocityContext velocityContext = VelocityUtils.initVelocityContext(genRowVo);
                for (GenTemplateVo genTemplateVo : genTemplateVoList) {
                    // 渲染模板
                    StringWriter stringWriter = new StringWriter();
                    try (StringReader stringReader = new StringReader(genTemplateVo.getContent())) {
                        Velocity.evaluate(velocityContext, stringWriter, genTemplateVo.getCode(), stringReader);
                    }
                    result.put(genTemplateVo.getCategory(), stringWriter.toString());
                }
            }
            // 母子表
            else {
                // 多表
                if (StrUtil.isEmpty(genRowVo.getChildRowId()) || ObjectUtil.isEmpty(genRowVo.getChildRowVo()))
                    throw new ServiceException("未找到指定的子表");
                if (StrUtil.isEmpty(genRowVo.getChildColumnId()) || ObjectUtil.isEmpty(genRowVo.getChildGenColumnVo()))
                    throw new ServiceException("未找到指定的子表关联列");
                VelocityInitializer.initVelocity();
                VelocityContext velocityContext = VelocityUtils.initVelocityContext(genRowVo);
                for (GenTemplateVo genTemplateVo : genTemplateVoList) {
                    // 渲染模板
                    StringWriter stringWriter = new StringWriter();
                    try (StringReader stringReader = new StringReader(genTemplateVo.getContent())) {
                        Velocity.evaluate(velocityContext, stringWriter, genTemplateVo.getCode(), stringReader);
                    }
                    result.put("MAIN_" + genTemplateVo.getCategory(), stringWriter.toString());
                }
                GenRowVo childRowVo = genRowVo.getChildRowVo();
                VelocityContext subVelocityContext = VelocityUtils.initVelocityContext(childRowVo);
                for (GenTemplateVo genTemplateVo : genTemplateVoList) {
                    if (TemplateType.VUE.name().equals(genTemplateVo.getType())) {
                        // 只有主表需要渲染 VUE 文件
                        continue;
                    }
                    // 渲染模板
                    StringWriter stringWriter = new StringWriter();
                    try (StringReader stringReader = new StringReader(genTemplateVo.getContent())) {
                        Velocity.evaluate(subVelocityContext, stringWriter, genTemplateVo.getCode(), stringReader);
                    }
                    result.put("SUB_" + genTemplateVo.getCategory(), stringWriter.toString());
                }
            }
            record.put(genRowVo.getBigClazz(), result);
        });
        return record;
    }

    /**
     * 下载
     *
     * @param rowIdList 主键列表
     * @return 下载文件
     */
    @Override
    public byte[] download(List<String> rowIdList) {
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        ZipOutputStream zip = new ZipOutputStream(outputStream);
        List<GenRowVo> genRowVoList = voList(new LambdaQueryWrapper<GenRow>().in(GenRow::getId, rowIdList));
        if (ObjectUtil.isEmpty(genRowVoList)) throw new ServiceException("未找到数据");
        renderGenRowVoList(genRowVoList);
        renderChildGenRowVoList(genRowVoList);
        genRowVoList.forEach(genRowVo -> {
            if (ObjectUtil.isEmpty(genRowVo.getCategoryId())) throw new ServiceException("未指定使用的模板分类");
            List<GenTemplateVo> genTemplateVoList = genRowVo.getGenTemplateVoList();
            if (ObjectUtil.isEmpty(genTemplateVoList)) throw new ServiceException("未找到模板列表");
            // 单表
            if (StrUtil.isEmpty(genRowVo.getChildRowId())) {
                // 单表
                VelocityInitializer.initVelocity();
                VelocityContext velocityContext = VelocityUtils.initVelocityContext(genRowVo);
                for (GenTemplateVo genTemplateVo : genTemplateVoList) {
                    // 渲染模板
                    StringWriter stringWriter = new StringWriter();
                    try (StringReader stringReader = new StringReader(genTemplateVo.getContent())) {
                        Velocity.evaluate(velocityContext, stringWriter, genTemplateVo.getCode(), stringReader);
                    }
                    try {
                        // 添加到 zip
                        zip.putNextEntry(new ZipEntry(VelocityUtils.getFileName(genTemplateVo, genRowVo)));
                        IOUtils.write(stringWriter.toString(), zip, Constants.UTF_8);
                        IOUtils.closeQuietly(stringWriter);
                        zip.flush();
                        zip.closeEntry();
                    } catch (IOException e) {
                        log.error("渲染模板失败，表名：" + genRowVo.getName(), e);
                    }
                }
            }
            // 母子表
            else {
                // 多表
                if (StrUtil.isEmpty(genRowVo.getChildRowId()) || ObjectUtil.isEmpty(genRowVo.getChildRowVo()))
                    throw new ServiceException("未找到指定的子表");
                if (StrUtil.isEmpty(genRowVo.getChildColumnId()) || ObjectUtil.isEmpty(genRowVo.getChildGenColumnVo()))
                    throw new ServiceException("未找到指定的子表关联列");
                VelocityInitializer.initVelocity();
                VelocityContext velocityContext = VelocityUtils.initVelocityContext(genRowVo);
                for (GenTemplateVo genTemplateVo : genTemplateVoList) {
                    // 渲染模板
                    StringWriter stringWriter = new StringWriter();
                    try (StringReader stringReader = new StringReader(genTemplateVo.getContent())) {
                        Velocity.evaluate(velocityContext, stringWriter, genTemplateVo.getCode(), stringReader);
                    }
                    try {
                        // 添加到 zip
                        zip.putNextEntry(new ZipEntry("MAIN_" + VelocityUtils.getFileName(genTemplateVo, genRowVo)));
                        IOUtils.write(stringWriter.toString(), zip, Constants.UTF_8);
                        IOUtils.closeQuietly(stringWriter);
                        zip.flush();
                        zip.closeEntry();
                    } catch (IOException e) {
                        log.error("渲染模板失败，表名：" + genRowVo.getName(), e);
                    }
                }
                GenRowVo childRowVo = genRowVo.getChildRowVo();
                VelocityContext subVelocityContext = VelocityUtils.initVelocityContext(childRowVo);
                for (GenTemplateVo genTemplateVo : genTemplateVoList) {
                    if (TemplateType.VUE.name().equals(genTemplateVo.getType())) {
                        // 只有主表需要渲染 VUE 文件
                        continue;
                    }
                    // 渲染模板
                    StringWriter stringWriter = new StringWriter();
                    try (StringReader stringReader = new StringReader(genTemplateVo.getContent())) {
                        Velocity.evaluate(subVelocityContext, stringWriter, genTemplateVo.getCode(), stringReader);
                    }
                    try {
                        // 添加到 zip
                        zip.putNextEntry(new ZipEntry("SUB_" + VelocityUtils.getFileName(genTemplateVo, genRowVo)));
                        IOUtils.write(stringWriter.toString(), zip, Constants.UTF_8);
                        IOUtils.closeQuietly(stringWriter);
                        zip.flush();
                        zip.closeEntry();
                    } catch (IOException e) {
                        log.error("渲染模板失败，子表名：" + genRowVo.getName(), e);
                    }
                }
            }
        });
        IOUtils.closeQuietly(zip);
        return outputStream.toByteArray();
    }

    /**
     * 新增 / 修改 前校验
     *
     * @param genRowBo 校验用业务对象
     * @return 数据库操作对象
     */
    private GenRow addAndEditValidBo(GenRowBo genRowBo) {
        GenRow genRow = ConvertUtils.convert(genRowBo, GenRow.class);
        if (ObjectUtil.isNull(genRow))
            throw new ServiceException("待校验对象为空");
        List<ValidateBos> validateBosList = Stream.of(
                ValidateUtils.createNeValidateBos(ValidateUtils.createValidateBo(GenRow::getId, genRow.getId(), "主键")),
                ValidateUtils.createEqValidateBos(ValidateUtils.createValidateBo(GenRow::getCategoryId, genRow.getCategoryId(), "分类ID")),
                ValidateUtils.createOrEqValidateBos(
                        ValidateUtils.createValidateBo(GenRow::getNo, genRow.getNo(), "编码"),
                        ValidateUtils.createValidateBo(GenRow::getName, genRow.getName(), "名称"),
                        ValidateUtils.createValidateBo(GenRow::getComment, genRow.getComment(), "表描述"),
                        ValidateUtils.createValidateBo(GenRow::getClazz, genRow.getClazz(), "类名称"),
                        ValidateUtils.createValidateBo(GenRow::getBigClazz, genRow.getBigClazz(), "大写类名称"),
                        ValidateUtils.createValidateBo(GenRow::getRemark, genRow.getRemark(), "备注"))
        ).collect(Collectors.toList());
        // 唯一校验
        ValidateUtils.uniqueValidate(this::countWrapper, validateBosList);
        if (StrUtil.isEmpty(genRow.getId())) {
            // 新增
            return genRow;
        } else {
            // 修改
            GenRow dbGenRow = getById(genRow.getId());
            BeanUtil.copyProperties(genRow, dbGenRow, true);
            return dbGenRow;
        }
    }

    /**
     * 删除前校验
     *
     * @param idList 主键列表
     * @return 主键列表
     */
    private List<String> delValid(List<String> idList) {
        if (ObjectUtil.isNull(idList))
            throw new ServiceException("待校验主键列表为空");
        return idList;
    }

    /**
     * 渲染视图
     *
     * @param genRowVoList 视图列表
     * @return 渲染后的视图列表
     */
    private List<GenRowVo> renderGenRowVoList(List<GenRowVo> genRowVoList) {
        if (ObjectUtil.isNotEmpty(genRowVoList)) {
            // todo 扩展信息填入
            List<String> rowIdList = genRowVoList.stream().map(GenRowVo::getId).collect(Collectors.toList());
            List<GenColumnVo> genColumnVoList = genColumnService.voList(new LambdaQueryWrapper<GenColumn>().in(GenColumn::getRowId, rowIdList));
            Map<String, List<GenColumnVo>> rowIdByGenColumnVoListToMap = genColumnVoList.stream().collect(Collectors.groupingBy(GenColumnVo::getRowId));
            genRowVoList.forEach(genRowVo -> {
                List<GenColumnVo> genColumnVos = rowIdByGenColumnVoListToMap.get(genRowVo.getId());
                if (ObjectUtil.isNotEmpty(genColumnVos)) {
                    genRowVo.setGenColumnVoList(genColumnVos);
                    List<GenColumnVo> primaryGenColumnVoList = genColumnVos.stream().filter(GenColumnVo::getPrimary).collect(Collectors.toList());
                    genRowVo.setPrimaryGenColumnVo(primaryGenColumnVoList.isEmpty() ? null : primaryGenColumnVoList.get(0));
                }
            });

            List<String> categoryIdList = genRowVoList.stream().map(GenRowVo::getCategoryId).collect(Collectors.toList());
            if (ObjectUtil.isNotEmpty(categoryIdList)) {
                List<GenCategoryVo> genCategoryVoList = genCategoryService.voList(new LambdaQueryWrapper<GenCategory>().in(GenCategory::getId, categoryIdList));
                Map<String, GenCategoryVo> categoryIdByGenCategoryVoToMap = genCategoryVoList.stream().collect(Collectors.toMap(GenCategoryVo::getId, Function.identity()));
                genRowVoList.forEach(genRowVo -> genRowVo.setGenCategoryVo(categoryIdByGenCategoryVoToMap.get(genRowVo.getCategoryId())));
                List<GenTemplateVo> genTemplateVoList = genTemplateService.voList(new LambdaQueryWrapper<GenTemplate>().in(GenTemplate::getCategoryId, categoryIdList));
                Map<String, List<GenTemplateVo>> categoryIdByGenTemplateVoListToMap = genTemplateVoList.stream().collect(Collectors.groupingBy(GenTemplateVo::getCategoryId));
                genRowVoList.forEach(genRowVo -> genRowVo.setGenTemplateVoList(categoryIdByGenTemplateVoListToMap.get(genRowVo.getCategoryId())));
            }
        }
        return genRowVoList;
    }

    /**
     * 渲染子表
     *
     * @param genRowVoList 视图列表
     * @return 渲染后的视图列表
     */
    private List<GenRowVo> renderChildGenRowVoList(List<GenRowVo> genRowVoList) {
        if (ObjectUtil.isNotEmpty(genRowVoList)) {
            List<String> childRowIdList = genRowVoList.stream().map(GenRowVo::getChildRowId).collect(Collectors.toList());
            if (ObjectUtil.isNotEmpty(childRowIdList)) {
                List<GenRowVo> childGenRowVoList = voList(new LambdaQueryWrapper<GenRow>().in(GenRow::getId, childRowIdList));
                renderGenRowVoList(childGenRowVoList);
                Map<String, GenRowVo> rowIdByGenRowVoToMap = childGenRowVoList.stream().collect(Collectors.toMap(GenRowVo::getId, Function.identity()));
                genRowVoList.forEach(genRowVo -> genRowVo.setChildRowVo(rowIdByGenRowVoToMap.get(genRowVo.getChildRowId())));
                genRowVoList.forEach(genRowVo -> {
                    List<GenColumnVo> childGenColumnVoList = genRowVo.getChildRowVo().getGenColumnVoList();
                    if (ObjectUtil.isNotEmpty(childGenColumnVoList)) {
                        List<GenColumnVo> childGenColumnVos = childGenColumnVoList.stream().filter(genColumnVo -> genColumnVo.getId().equals(genRowVo.getChildColumnId())).collect(Collectors.toList());
                        if (ObjectUtil.isNotEmpty(childGenColumnVos)) {
                            genRowVo.setChildGenColumnVo(childGenColumnVos.get(0));
                        }
                    }
                });
            }
        }
        return genRowVoList;
    }

    /**
     * 构建查询条件
     *
     * @param queryGenRow 查询用业务对象
     * @return 查询条件
     */
    private MPJLambdaWrapper<GenRow> buildQueryWrapper(QueryGenRow queryGenRow) {
        MPJLambdaWrapper<GenRow> lambdaQueryWrapper = new MPJLambdaWrapper<GenRow>().selectAll(GenRow.class);
        lambdaQueryWrapper.eq(StrUtil.isNotEmpty(queryGenRow.getId()), GenRow::getId, queryGenRow.getId());
        lambdaQueryWrapper.eq(StrUtil.isNotEmpty(queryGenRow.getNo()), GenRow::getNo, queryGenRow.getNo());
        lambdaQueryWrapper.like(StrUtil.isNotEmpty(queryGenRow.getName()), GenRow::getName, queryGenRow.getName());
        lambdaQueryWrapper.eq(StrUtil.isNotEmpty(queryGenRow.getComment()), GenRow::getComment, queryGenRow.getComment());
        lambdaQueryWrapper.eq(StrUtil.isNotEmpty(queryGenRow.getCategoryId()), GenRow::getCategoryId, queryGenRow.getCategoryId());
        lambdaQueryWrapper.eq(StrUtil.isNotEmpty(queryGenRow.getChildRowId()), GenRow::getChildRowId, queryGenRow.getChildRowId());
        lambdaQueryWrapper.eq(StrUtil.isNotEmpty(queryGenRow.getChildColumnId()), GenRow::getChildColumnId, queryGenRow.getChildColumnId());
        lambdaQueryWrapper.eq(StrUtil.isNotEmpty(queryGenRow.getPack()), GenRow::getPack, queryGenRow.getPack());
        lambdaQueryWrapper.eq(StrUtil.isNotEmpty(queryGenRow.getClazz()), GenRow::getClazz, queryGenRow.getClazz());
        lambdaQueryWrapper.eq(StrUtil.isNotEmpty(queryGenRow.getBigClazz()), GenRow::getBigClazz, queryGenRow.getBigClazz());
        lambdaQueryWrapper.eq(StrUtil.isNotEmpty(queryGenRow.getModule()), GenRow::getModule, queryGenRow.getModule());
        lambdaQueryWrapper.eq(StrUtil.isNotEmpty(queryGenRow.getBusiness()), GenRow::getBusiness, queryGenRow.getBusiness());
        lambdaQueryWrapper.eq(StrUtil.isNotEmpty(queryGenRow.getAuthor()), GenRow::getAuthor, queryGenRow.getAuthor());
        lambdaQueryWrapper.eq(StrUtil.isNotEmpty(queryGenRow.getAbility()), GenRow::getAbility, queryGenRow.getAbility());
        lambdaQueryWrapper.eq(StrUtil.isNotEmpty(queryGenRow.getType()), GenRow::getType, queryGenRow.getType());
        lambdaQueryWrapper.eq(StrUtil.isNotEmpty(queryGenRow.getPath()), GenRow::getPath, queryGenRow.getPath());
        lambdaQueryWrapper.eq(StrUtil.isNotEmpty(queryGenRow.getMenuId()), GenRow::getMenuId, queryGenRow.getMenuId());
        lambdaQueryWrapper.eq(ObjectUtil.isNotEmpty(queryGenRow.getGenerated()), GenRow::getGenerated, queryGenRow.getGenerated());
        lambdaQueryWrapper.eq(StrUtil.isNotEmpty(queryGenRow.getOptions()), GenRow::getOptions, queryGenRow.getOptions());
        lambdaQueryWrapper.eq(ObjectUtil.isNotEmpty(queryGenRow.getSort()), GenRow::getSort, queryGenRow.getSort());
        lambdaQueryWrapper.like(StrUtil.isNotEmpty(queryGenRow.getRemark()), GenRow::getRemark, queryGenRow.getRemark());
        return lambdaQueryWrapper;
    }

}